package com.ht.ui.report;

import com.ht.aems.fesmodel.HisDataProvider;
import com.ht.aems.fesmodel.persist.HisDataSqlPersist;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.view.JRViewer;

import javax.swing.*;
import java.math.BigDecimal;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 *
 * @author Dong Shufeng
 *         Date: 2010-8-16
 */
public class DayReportSource implements JRDataSource {//todo: not finished...
    private static SimpleDateFormat hourformat = new SimpleDateFormat("HH:mm");

    Date date;
    int columnNum = 1;
    HisDataProvider hisDataProvider = new HisDataSqlPersist();
    int rowCount;
    boolean isFirstTime = true;

    private int tmp1 = -2;
    private int tmp2 = -2;
    private int nid = -1;

    private List<Long> times;
    private List<Double> values;

    public DayReportSource() {
    }

    public DayReportSource(int nid, int columnNum, Date date) {
        this.columnNum = columnNum;
        this.date = date;
        this.nid = nid;
        loadValueFormDB();
        if (times == null)
            rowCount = 0;
        else
            rowCount = times.size() / columnNum;
    }

    public DayReportSource(Map<Long, Double> data, int columnNum) {
        this.columnNum = columnNum;
        times = new ArrayList<Long>(data.keySet());
        values = new ArrayList<Double>(times.size());
        for (Long key : times)
            values.add(data.get(key));
        if (values == null)
            rowCount = 0;
        else
            rowCount = values.size() / columnNum;
    }

    public boolean next() throws JRException {
        rowCount--;
        tmp1 = -columnNum - 1;
        tmp2 = -columnNum - 1;
        return rowCount > 0;
    }

    public Object getFieldValue(JRField f) {
        if (f.getValueClassName().equals(Date.class.getName())) {
            tmp1++;
            int index = times.size() - rowCount * columnNum + tmp1;
            if (times.size() > index)
                return new Date(times.get(index));
            else return null;
        } else {
            tmp2++;
            int index = values.size() - rowCount * columnNum + tmp2;
            if (values.size() > index) {
                return values.get(index);
            } else return null;
        }
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public List<Double> getValues() {
        return values;
    }

    public List<Long> getTimes() {
        return times;
    }

    private void loadValueFormDB() {
        Calendar c = Calendar.getInstance();
        c.setTime(date);

        Calendar start = Calendar.getInstance();
        start.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DATE), 0, 0, 0);

        Map<Long, Double> data = hisDataProvider.getMinuteAnalogInSameDay(nid, start.getTimeInMillis(), start.getTimeInMillis() + 24l * 3600l * 1000l - 1000l);
        times = new ArrayList<Long>(data.keySet());
        values = new ArrayList<Double>(times.size());
        Collections.sort(times);
        for (Long key : times)
            values.add(data.get(key));
    }


    public int getColumnNum() {
        return columnNum;
    }

    public void setColumnNum(int columnNum) {
        this.columnNum = columnNum;
    }

    public int getNid() {
        return nid;
    }

    public void setNid(int nid) {
        this.nid = nid;
    }

    public static JPanel getViewer(String title, String resource, Date date) {
        return getViewer(title, SimpleAnalogJrMaker.class.getResource(resource), date);
    }


    public static JPanel getViewer(String title, URL resource, Date date) {
        JasperReport jasperReport;
        HashMap<String, String> pMap = new HashMap<String, String>();
        pMap.put("title", title);
        //todo:
        try {
            jasperReport = (JasperReport) JRLoader.loadObject(resource);
        } catch (JRException e) {
            e.printStackTrace();
            return null;
        }
        JasperPrint jasperPrint;
        try {
            JRField[] fields = jasperReport.getFields();
            int nid = 0;
            for (JRField f : fields) {
                if (f.getValueClassName().equals(Double.class.getName())) {
                    nid = Integer.parseInt(f.getName());
                    break;
                }
            }
            DayReportSource source = new DayReportSource(nid, fields.length / 2, date);
            jasperPrint = JasperFillManager.fillReport(jasperReport, pMap, source);
        } catch (JRException e) {
            e.printStackTrace();
            return null;
        }
        return new JRViewer(jasperPrint);
    }

    public static JPanel getViewer(String title, Map<Long, Double> data, URL resource, String date, List<Double> limit) {
        JasperReport jasperReport;
        JasperPrint jasperPrint;
        try {
            double average = 0;
            DayReportSource source = new DayReportSource(data, 2);
            int upperLimit = 0;
            int lowerLimit = 0;
            double maxV = Double.MIN_VALUE;
            double minV = Double.MAX_VALUE;
            int maxIndex = 0;
            int minIndex = 0;
            for (int i = 0; i < source.getValues().size(); i++) {
                if (source.getValues().get(i) > limit.get(0)) {
                    upperLimit++;
                } else if (source.getValues().get(i) < limit.get(1)) {
                    lowerLimit++;
                }
                if (source.getValues().get(i) > maxV) {
                    maxIndex = i;
                    maxV = source.getValues().get(i);
                } else if (source.getValues().get(i) < minV) {
                    minIndex = i;
                    minV = source.getValues().get(i);
                }
                average += source.getValues().get(i);
            }
            HashMap<String, Object> pMap = new HashMap<String, Object>();
            pMap.put("title", title);
            pMap.put("date", date);
            pMap.put("upperLimit", upperLimit);
            pMap.put("lowerLimit", lowerLimit);
            pMap.put("maxValue", source.getValues().get(maxIndex));
            pMap.put("minValue", source.getValues().get(minIndex));
            pMap.put("maxTime", hourformat.format(source.getTimes().get(maxIndex)));
            pMap.put("minTime", hourformat.format(source.getTimes().get(minIndex)));
            pMap.put("average", new BigDecimal(average / data.size()).setScale(2, java.math.BigDecimal.ROUND_HALF_UP).doubleValue());
            pMap.put("dataCount", data.size());
            jasperReport = (JasperReport) JRLoader.loadObject(resource);
            jasperPrint = JasperFillManager.fillReport(jasperReport, pMap, source);
        } catch (JRException e) {
            e.printStackTrace();
            return null;
        }
        return new JRViewer(jasperPrint);
    }
}